﻿using PlantsZombies.Common.Bullet;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace PlantsZombies.Common
{
    public unsafe abstract class GameObject
    {
        private readonly SpeciesType _speciesType;
        protected ImageObject[] _images;
        protected int _life;
        private Size _size;
        private readonly int _height;
        private readonly int _width;
        private readonly int _bulletWidth;
        private readonly int _bulletHeight;
        public GameObject(SpeciesType speciesType, int life, Size size)
        {
            _speciesType = speciesType;
            _life = life;
            _size = size;
            _height = size.Height;
            _width = size.Width;
            Damage = 1;
            Id=Guid.NewGuid().ToString();
        }
        public string Id {  get; private set; }
        public Size Size { get { return _size; } set { _size = value; } }
        public int Life { get { return _life; } set { _life = value; } }
        public SpeciesType SpeciesType { get { return _speciesType; } }
        public virtual void Move(ListGameObject* ptr)
        {
            if (_bulletObject != null)
                _bulletObject.Move(ptr);
        }
        /// <summary>
        /// 伤害，默认1
        /// </summary>
        public int Damage { get; set; }
        public int StartX { get; set; }
        public int StartY { get; set; }
        public int CellWidth { get; set; }
        public int CellHeight { get; set; }
        public float ZoomX { get; set; }
        public float ZoomY { get; set; }
        public int Row { get; set; }
        public int Column { get; set; }
        public int MaxRow { get; set; }
        public int UseMaxColumn { get; set; }
        public int MaxColumn { get; set; }
        public virtual void UpdateState()
        {
            this.Location = new Point(StartX + Column * CellWidth, StartY + Row * CellHeight);
            this.Size = new Size((int)(_width * ZoomX), (int)(_height * ZoomY));
            if (_bulletObject != null)
                _bulletObject.UpdateState(ZoomX, ZoomY);
        }
        public Point Location { get; set; }
        public Action CompletionCallback;
        public virtual void Attack(ListGameObject* ptr)
        {
            if (_bulletObject != null)
                _bulletObject.Attack(ptr);
        }
        protected int _curPlayIndex = 0;
        public int CurPlayIndex { get { return _curPlayIndex; } }
        public virtual void Play(IntPtr hdc)
        {
            PlayBody(hdc);
            PlayWeapon(hdc);
        }
        protected virtual void PlayBody(IntPtr hdc)
        {
            var image = _images[_curPlayIndex];
            GDI32.DrawImageTransparenc(hdc, image.BitmapPtr, Location.X + (CellWidth - _size.Width) / 2, Location.Y + (CellHeight - _size.Height) / 2, image.Width, image.Height, _size.Width, _size.Height);
            if (++_curPlayIndex >= _images.Length)
                _curPlayIndex = 0;
        }
        protected virtual void PlayWeapon(IntPtr hdc)
        {
            if (_bulletObject != null)
                _bulletObject.Play(hdc);
        }

        public void SetImage(string[] paths)
        {
            fixed (String* ptr = paths)
            {
                ImageObject[] ib = new ImageObject[paths.Length];
                fixed (ImageObject* sp = ib)
                {
                    for (int i = 0; i < paths.Length; i++)
                    {
                        *(sp + i) = new ImageObject(*(ptr + i));
                    }
                }
                SetImage(ib);
            }
        }
        public void SetImage(Bitmap[] iamges)
        {
            fixed (Bitmap* ptr = iamges)
            {
                ImageObject[] ib = new ImageObject[iamges.Length];
                fixed (ImageObject* sp = ib)
                {
                    for (int i = 0; i < iamges.Length; i++)
                    {
                        *(sp + i) = new ImageObject(*(ptr + i));
                    }
                }
                SetImage(ib);
            }
        }
        public void SetImage(ImageObject[] iamges)
        {
            _images = iamges;
        }
        #region 武器
        private BulletObject _bulletObject;
        public BulletObject Bullet
        {
            get { return _bulletObject; }
        }
        public void SetBullet(BulletObject bulletObject)
        {
            _bulletObject = bulletObject;
        }
        #endregion
        public bool IsZombie()
        {
            return this.SpeciesType.GetHashCode() >= SpeciesType.OrdinaryZombie.GetHashCode();
        }
        public Action MouseDownCallback;
        public virtual void MouseDown(object sender, MouseEventArgs e)
        {
        }
    }
}
